// 优化滚动栏位。
// 用于上千个滚动节点的时候
// 比如首页关卡
cc.Class({
    extends: cc.Component,

    properties: {
        scrollView: cc.Node,
        loadlist: [],       // 加载内容
        Vertical: false,
        //间距
        gap_x: 0,
        gap_y: 0,
        item_size:null,
        start_size:null,
        end_size:null,
        default_prefab:null,
        start_prefab:null,
        end_prefab:null,
        load_node:cc.Node,  // 加载遮罩
    },
    //初始化
    init(loadlist,initFuc,options) {
        this.scrView = this.scrollView.getComponent(cc.ScrollView);
        this.content = this.scrView.content;
        this.height = this.content.height;
        this.width = this.content.width;
        this.loadlist = loadlist
        if(loadlist && loadlist.length){
            this.load_node.active = true
            he.load.loadResList(loadlist,this.loadPro.bind(this))
        }
        if(options){
          if(options.default){
            this.default_prefab = options.default
          }
          if(options.start){
            this.start_prefab = options.start
          }
          if(options.end){
            this.end_prefab = options.end
          }
        }
        this.initInfo = initFuc
        //scrollView监听事件
        this.scrollView.on('scrolling', this.on_scrolling, this);
    },
    // 赋值
    set_data(datas){
        this.clear_items();
        this.items = [];
        datas.forEach((data, index) => {
            let item = this.pack_item(index, data);
            this.items.push(item);
        });
        this.layout_items(0);   // 从初始开始排列数据
        this.resize_content();
        this.start_index = -1;
        this.stop_index = -1;
        if (this.Vertical) {
            this.content.y = 0;
        } else {
            this.content.x = 0;
        }
        if (this.items.length > 0) {
            this.on_scrolling();
        }
    },
    // 加载进度
    loadPro(err, res){
        if(err){
            he.error(err)
        }
        if(res){
            // 加载完成
            if(this.default_prefab && this.default_prefab == res.name){
              this.item_size = res.data.getContentSize()
            }
            if(this.start_prefab && this.start_prefab == res.name){
              this.start_size = res.data.getContentSize()
            }
            if(this.end_prefab && this.end_prefab == res.name){
              this.end_size = res.data.getContentSize()
            }
            if(he.load.checkLoadOver(this.loadlist)){ 
                // 创建单元按钮池子                
                for(let i = 0;i < this.loadlist.length; i++){
                    if(!he.pool.getPool(this.loadlist[i].pool)){
                      he.pool.createPoolSync(this.loadlist[i].pool,this.loadlist[i].num,cc.Prefab,this.loadlist[i].url)    
                    }
                }
                if(this.initInfo){
                    this.initInfo()
                }
                this.load_node.active = false
            }
        }
    },
    //滑动中回调
    on_scrolling(event) {
        // if(event){
        //   cc.log(event.getScrollOffset().toString())
        // }
        if (!this.items || !this.items.length) {
            return;
        }
        //垂直滚动
        if (this.Vertical) {
            let posy = this.content.y;
            if (posy < 0) {
                posy = 0;
            }
            if (posy > this.content.height - this.height) {
                posy = this.content.height - this.height;
            }
            // 单元锚点为Y朝上。
            // 所以记录当前遮罩内的内容
            let start = 0;
            let stop = this.items.length - 1;
            let viewport_start = -posy;
            // 一手超屏幕外也算
            // let viewport_stop = viewport_start - this.height;
            let viewport_stop = viewport_start - this.height;
            if(this.item_size){
              viewport_stop -= this.item_size.height * 1.5
            }
            while (this.items[start].y - this.items[start].height > viewport_start) {
                start++;
            }
            while (this.items[stop].y < viewport_stop) {
                stop--;
            }

            // 如果超过遮罩,并且不等于记录值则开始重新渲染
            if (start != this.start_index && stop != this.stop_index) {
                this.start_index = start;
                this.stop_index = stop;
                this.render_items();
            }
        } else { //水平滚动
            let posx = this.content.x;
            if (posx > 0) {
                posx = 0;
            }
            if (posx < this.width - this.content.width) {
                posx = this.width - this.content.width;
            }
            let start = 0;
            let stop = this.items.length - 1;
            let viewport_start = -posx;
            let viewport_stop = viewport_start + this.width;
            while (this.items[start].x + this.items[start].width < viewport_start) {
                start++;
            }
            while (this.items[stop].x > viewport_stop) {
                stop--;
            }
            if (start != this.start_index && stop != this.stop_index) {
                this.start_index = start;
                this.stop_index = stop;
                this.render_items();
            }
        }
    },
    //生成node key为pool.name
    spawn_node(key) {
        let node = he.pool.getElement(key)
        // console.log(node)
        if(!node.active)
            node.active = true;
        node.parent = this.content;
        return node;
    },
    //回收item
    recycle_item(item) {
        if (item.node && cc.isValid(item.node)) {
            he.pool.putElement(item.name,item.node)
            item.node = null;
        }
    },
    //清除items
    clear_items() {
        if (this.items) {
            this.items.forEach((item) => {
                this.recycle_item(item);
            });
        }
    },
    //渲染items
    render_items() {
        let item;
        for (let i = 0; i < this.start_index; i++) {
            item = this.items[i];
            // he.log("loaditem",item)
            if (item.node) {
                this.recycle_item(item);
            }
        }
        for (let i = this.items.length - 1; i > this.stop_index; i--) {
            item = this.items[i];
            if (item.node) {
                this.recycle_item(item);
            }
        }
        for (let i = this.start_index; i <= this.stop_index + 1; i++) {
            if (!this.items[i]) {
                return

            }
            item = this.items[i];
            if (!item.node) {
                item.node = this.spawn_node(item.name);
                this.item_setter(item.node, item.data);
            }
            item.node.setPosition(item.x, item.y);
            item.node.zIndex = cc.macro.MAX_ZINDEX - i
        }
    },
    // 增加实例化数组
    pack_item(index, data) {
        let node = this.spawn_node(data.name);
        let [width, height] = this.item_setter(node, data);
        let item = {
            x: 0,
            y: 0,
            width: width,
            height: height,
            data: data,
            node: node,
            name: data.name
        };
        this.recycle_item(item);
        return item;
    },
    // item具体赋值
    item_setter(item, data) {
        let script_name = ''
        if(data.script){
            script_name = data.script
        }else{
            script_name = data.name
        }
        let script = item.getComponent(script_name)
        if(script){
            script.initInfo(data)
        }
        return [item.width, item.height];
    },
    // 布局items
    layout_items(start) {
        if (this.items.length <= 0) {
            return;
        }
        let start_pos = 0;
        if (start > 0) {
            let prev_item = this.items[start - 1];
            if (this.Vertical) {
                start_pos = prev_item.y - prev_item.height - this.gap_y;
            } else {
                start_pos = prev_item.x + prev_item.width + this.gap_x;
            }
        }
        for (let index = start, stop = this.items.length; index < stop; index++) {
            let item = this.items[index];
            if (this.Vertical) {
                item.x = 0;
                item.y = start_pos;
                start_pos -= item.height + this.gap_y;
            } else {
                item.y = 0;
                item.x = start_pos;
                start_pos += item.width + this.gap_x;
            }
        }
    },
    // 调整content
    resize_content() {
        if (this.items.length <= 0) {
            this.content.width = 0;
            this.content.height = 0;
            return;
        }
        let last_item = this.items[this.items.length - 1];
        if (this.Vertical) {
            this.content.height = Math.max(this.height, last_item.height - last_item.y);
        } else {
            this.content.width = Math.max(this.width, last_item.x + last_item.width);
        }
    },
    // 插入数据
    insert_data(index, datas) {
        if (datas.length == 0) {
            // console.log("没有要添加的数据");
            return;
        }
        if (!this.items) {
            this.items = [];
        }
        if (index < 0 || index > this.items.length) {
            console.log("无效的index", index);
            return;
        }
        let is_append = index == this.items.length;
        let items = [];
        datas.forEach((data, index) => {
            let item = this.pack_item(index, data);
            items.push(item);
        });
        this.items.splice(index, 0, ...items);
        this.layout_items(index);
        this.resize_content();
        this.start_index = -1;
        this.stop_index = -1;
        this.on_scrolling();
    },
    //追加数据
    append_data(datas) {
        if (!this.items) {
            this.items = [];
        }
        this.insert_data(this.items.length, datas);
    },
    //滑动到底
    scroll_to_end() {
        if (this.Vertical) {
            this.scrView.getComponent(cc.ScrollView).scrollToBottom(1);
        } else {
            this.scrView.getComponent(cc.ScrollView).scrollToRight(1);
        }
    },
    scroll_to_start(){
        if (this.Vertical) {
            this.scrView.getComponent(cc.ScrollView).scrollToTop(1);
        } else {
            this.scrView.getComponent(cc.ScrollView).scrollToLeft(1);
        }
    },
    onDestroy(){
        this.destroy_items()
    },
    destroy_items() {
        this.clear_items();
        this.items = null;
        for(let i = 0;i < this.loadlist.length; i++){
            he.pool.delPool(this.loadlist[i].pool)
        }
        if (cc.isValid(this.scrollview)) {
            this.scrollview.off("scrolling", this.on_scrolling, this);
        }
    },


});